package org.dubnation.base.interceptors;

import org.dubnation.auth.context.LoginContext;
import org.dubnation.auth.domain.EmployeeLogin;
import org.dubnation.base.annotation.DubnationPermission;
import org.dubnation.org.service.IEmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;

@Component
public class AuthenticInterceptor implements HandlerInterceptor {

    @Autowired
    private IEmployeeService service;

    /**
     * 前置拦截，拦截请求判断是否登录，授权
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //接收前端传的token
        String token = request.getHeader("token");
        //判断token是否为空
        if (StringUtils.isEmpty(token)){
            //前端传的token为空，没有登录过
            response.getWriter().println("{\"success\":false,\"message\":\"noLogin\"}");
            return false;
        }
        //判断后端存储在全局Map中的token是否存在
        Object user = LoginContext.messageMap.get(token);
        if (Objects.isNull(user)){
            //后端map中没有登录信息
            response.getWriter().println("{\"success\":false,\"message\":\"noLogin\"}");
            return false;
        }

        /*
        * 鉴权
        * */
        //拦截请求之后需要判断该用户是否有访问资源的权限
        if (!(handler instanceof HandlerMethod)){
            return false;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        //获取Controller类的名字，判断是否有权限
        DubnationPermission clazzAnnotation = handlerMethod.getBeanType().getAnnotation(DubnationPermission.class);
        if (StringUtils.isEmpty(clazzAnnotation)){
            //该Controller类资源没有权限，任何用户都可以访问
            return true;
        }
        //类有权限，判断访问的方法是否有权限
        DubnationPermission methodAnnotation = handlerMethod.getMethod().getAnnotation(DubnationPermission.class);
        if (StringUtils.isEmpty(methodAnnotation)){
            //访问的方法没有权限，放行
            return true;
        }
        //访问的资源有权限
        //获取该资源的权限
        String clazzName = handlerMethod.getBeanType().getSimpleName();
        String methodName = handlerMethod.getMethod().getName();
        String resourcePermission = clazzName + ":" + methodName; //访问的资源权限
        //获取访问该资源用户的权限
        EmployeeLogin user1 = (EmployeeLogin) user;  //强转之后必须接收才能取到值
        List<String> userPermissionSn =  service.getPermissionSn(user1.getId());
        //判断用户拥有的权限sn是否与被访问资源的权限sn一致
        if (!userPermissionSn.contains(resourcePermission)){
            //该用户没有访问该资源的权限
            response.getWriter().println("{\"success\":false,\"message\":\"noPermission\"}");
            return false;
        }
        return true;
    }
}
